import { RuntimeError } from '@ibiz-template/core';
import {
  MDControlController,
  IChartEvent,
  IChartController,
  IChartState,
  MDCtrlLoadParams,
} from '@ibiz-template/runtime';
import { IDEChart } from '@ibiz/model-core';
import { EChartsOption, EChartsType, init } from 'echarts';
import { ChartOptionsGenerator } from './generator/chart-options-generator';
import { ChartService } from './chart.service';

export class ChartController
  extends MDControlController<IDEChart, IChartState, IChartEvent>
  implements IChartController
{
  declare service: ChartService;

  /**
   * echarts对象
   * @author lxm
   * @date 2023-06-07 09:36:58
   * @type {EChartsType}
   */
  chart?: EChartsType;

  generator!: ChartOptionsGenerator;

  /**
   * 最终使用的echarts配置
   * @author lxm
   * @date 2023-06-07 09:51:09
   * @type {EChartsOption}
   */
  options?: EChartsOption;

  protected async onCreated(): Promise<void> {
    await super.onCreated();
    this.service = new ChartService(this.model);
    await this.service.init(this.context);
    this.generator = new ChartOptionsGenerator(this.model);
    await this.generator.loadCodeList(this.context, this.params);

    // 监听resize调整图表大小
    window.addEventListener('resize', this.resizeChart);
  }

  async afterLoad(args: MDCtrlLoadParams, items: IData[]): Promise<IData[]> {
    const result = await super.afterLoad(args, items);
    this.calcOptions();
    return result;
  }

  /**
   * 初始化echarts对象
   * @author lxm
   * @date 2023-06-07 09:37:05
   * @param {HTMLElement} dom
   */
  initChart(dom: HTMLElement): void {
    if (!dom) {
      throw new RuntimeError('图表初始化的dom元素不存在！');
    }
    this.chart = init(dom);
    this.chart.on('click', params => {
      const srfkey = this.generator.getSrfkeyByParams(params);
      const activeData = this.state.items.find(item => item.srfkey === srfkey);
      console.log('实体数据', activeData);
    });
  }

  /**
   * 根据数据计算最终的options
   * 并刷新echarts
   * @author lxm
   * @date 2023-06-07 09:58:00
   * @param {IData[]} [data=this.state.items]
   */
  calcOptions(data: IData[] = this.state.items): void {
    this.options = this.generator.calcOptionsByData(data);
    this.updateChart();
  }

  /**
   * 更新echart图表
   * @author lxm
   * @date 2023-06-07 10:03:48
   */
  updateChart(): void {
    if (!this.chart) {
      throw new RuntimeError('chart对象没有正确初始化');
    }
    if (!this.options) {
      throw new RuntimeError('options还没计算');
    }
    this.chart.setOption(this.options);
    this.resizeChart();
  }

  /**
   * 刷新图表的大小
   * @author lxm
   * @date 2023-06-09 09:37:25
   */
  resizeChart(): void {
    if (this.chart) {
      this.chart.resize();
    }
  }

  protected async onDestroyed(): Promise<void> {
    window.removeEventListener('resize', this.resizeChart);
    await super.onDestroyed();
    this.chart?.dispose();
  }
}
